package org.dbstar.scheduler.actions;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.dbstar.scheduler.beans.Catalog;
import org.dbstar.scheduler.beans.CmdJobConf;
import org.dbstar.scheduler.beans.CompoundJobConf;
import org.dbstar.scheduler.beans.Job;
import org.dbstar.scheduler.beans.JobConf;
import org.dbstar.scheduler.beans.JobDefine;
import org.dbstar.scheduler.beans.JobDependency;
import org.dbstar.scheduler.beans.JobDependencyItem;
import org.dbstar.scheduler.beans.LoopJobConf;
import org.dbstar.scheduler.beans.OperateType;
import org.dbstar.scheduler.beans.ParameterDefine;
import org.dbstar.scheduler.beans.ParameterDefineType;
import org.dbstar.scheduler.control.CatalogController;
import org.dbstar.scheduler.control.JobConfController;
import org.dbstar.scheduler.control.JobController;
import org.dbstar.scheduler.control.JobDependencyController;
import org.dbstar.scheduler.control.exception.DaoException;
import org.dbstar.scheduler.identifier.Identifier;
import org.dbstar.scheduler.utils.JobUtils;
import org.dbstar.scheduler.utils.Utils;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;

/**
 * 新增/修改JobConf信息
 * 
 * @author 代波
 * @since 1.0.0
 * @version 1.0.0
 * @date 2012-4-9
 */
@Results({
		@Result(name = "success", location = "job-confs", type = "redirectAction", params = { "catalog", "${catalog}",
				"message", "${message}" }),
		@Result(name = "viewConf", location = "job-conf.action", type = "redirectAction", params = { "identifier",
				"${identifier}", "action", "view", "message", "${message}" }),
		@Result(name = "json", type = "json", params = { "root", "jsonRoot" }) })
public class JobConfAction extends ActionSupport {
	// 仅接收
	private JobController jobController;
	private JobDependencyController jobDependencyController;
	private Scheduler scheduler;
	private String action;

	// 仅传出
	private ParameterDefineType defineTypes[];
	private List<Catalog> catalogs;
	private JobConf conf;
	private List<Trigger> triggers;
	private List<JobDependency> dependencies;
	private String message;
	private List<Job> jobs;
	private List<JobConf> confs;
	private List<JobConf> parentConfs;
	private List<JobConf> fireConfs;
	private AjaxResult jsonRoot;

	// 接收并传出
	private CatalogController catalogController;
	private JobConfController jobConfController;
	private Identifier identifier;
	private int catalog;
	private String confName;
	private String confDesc;
	private String confType;
	private String confContent;
	private String paraName[];
	private ParameterDefineType paraType[];
	private String paraValue[];
	private Identifier subJob[];
	private String subJobPara[];
	private String subJobDepend[];
	private String subJobCondition[];
	private String loopVar;
	private String loopType;
	private String loopFrom;
	private String loopTo;
	private int loopStep;
	private boolean loopDependency;
	private String resource;
	private int maxRetry;

	// 仅接收
	public void setJobController(JobController jobController) {
		this.jobController = jobController;
	}

	public void setJobDependencyController(JobDependencyController jobDependencyController) {
		this.jobDependencyController = jobDependencyController;
	}

	public void setScheduler(Scheduler scheduler) {
		this.scheduler = scheduler;
	}

	public void setAction(String action) {
		this.action = action;
	}

	// 仅传出
	public ParameterDefineType[] getDefineTypes() {
		return defineTypes;
	}

	public List<Catalog> getCatalogs() {
		return catalogs;
	}

	public JobConf getConf() {
		return conf;
	}

	public List<Trigger> getTriggers() {
		return triggers;
	}

	public List<JobDependency> getDependencies() {
		return dependencies;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public List<Job> getJobs() {
		return jobs;
	}

	public List<JobConf> getConfs() {
		return confs;
	}

	public List<JobConf> getParentConfs() {
		return parentConfs;
	}

	public List<JobConf> getFireConfs() {
		return fireConfs;
	}

	public AjaxResult getJsonRoot() {
		return jsonRoot;
	}

	// 接收并传出
	public CatalogController getCatalogController() {
		return catalogController;
	}

	public void setCatalogController(CatalogController catalogController) {
		this.catalogController = catalogController;
	}

	public JobConfController getJobConfController() {
		return jobConfController;
	}

	public void setJobConfController(JobConfController jobConfController) {
		this.jobConfController = jobConfController;
	}

	public Identifier getIdentifier() {
		return identifier;
	}

	public void setIdentifier(Identifier identifier) {
		this.identifier = identifier;
	}

	public int getCatalog() {
		return catalog;
	}

	public void setCatalog(int catalog) {
		this.catalog = catalog;
	}

	public String getConfName() {
		return confName;
	}

	public void setConfName(String conf_name) {
		this.confName = conf_name;
	}

	public String getConfDesc() {
		return confDesc;
	}

	public void setConfDesc(String conf_desc) {
		this.confDesc = conf_desc;
	}

	public String getConfType() {
		return confType;
	}

	public void setConfType(String conf_type) {
		this.confType = conf_type;
	}

	public String getConfContent() {
		return confContent;
	}

	public void setConfContent(String conf_content) {
		this.confContent = conf_content;
	}

	public String[] getParaName() {
		return paraName;
	}

	public void setParaName(String[] paraName) {
		this.paraName = paraName;
	}

	public ParameterDefineType[] getParaType() {
		return paraType;
	}

	public void setParaType(ParameterDefineType[] paraDefine) {
		this.paraType = paraDefine;
	}

	public String[] getParaValue() {
		return paraValue;
	}

	public void setParaValue(String[] paraPattern) {
		this.paraValue = paraPattern;
	}

	public Identifier[] getSubJob() {
		return subJob;
	}

	public void setSubJob(Identifier[] subJob) {
		this.subJob = subJob;
	}

	public String[] getSubJobPara() {
		return subJobPara;
	}

	public void setSubJobPara(String[] subJobPara) {
		this.subJobPara = subJobPara;
	}

	public String[] getSubJobDepend() {
		return subJobDepend;
	}

	public void setSubJobDepend(String[] subJobDepend) {
		this.subJobDepend = subJobDepend;
	}

	public String[] getSubJobCondition() {
		return subJobCondition;
	}

	public void setSubJobCondition(String[] subJobCondition) {
		this.subJobCondition = subJobCondition;
	}

	public String getLoopVar() {
		return loopVar;
	}

	public void setLoopVar(String loopVar) {
		this.loopVar = loopVar;
	}

	public String getLoopType() {
		return loopType;
	}

	public void setLoopType(String loopType) {
		this.loopType = loopType;
	}

	public String getLoopFrom() {
		return loopFrom;
	}

	public void setLoopFrom(String loopFrom) {
		this.loopFrom = loopFrom;
	}

	public String getLoopTo() {
		return loopTo;
	}

	public void setLoopTo(String loopTo) {
		this.loopTo = loopTo;
	}

	public int getLoopStep() {
		return loopStep;
	}

	public void setLoopStep(int loopStep) {
		this.loopStep = loopStep;
	}

	public boolean isLoopDependency() {
		return loopDependency;
	}

	public void setLoopDependency(boolean loopDependency) {
		this.loopDependency = loopDependency;
	}

	public String getResource() {
		return resource;
	}

	public void setResource(String resource) {
		this.resource = resource;
	}

	public int getMaxRetry() {
		return maxRetry;
	}

	public void setMaxRetry(int maxRetry) {
		this.maxRetry = maxRetry;
	}

	/**
	 * ajax 接口
	 * 
	 * @return
	 * @throws Exception
	 */
	public String json() throws Exception {
		defineTypes = ParameterDefineType.values();
		catalogs = Utils.getAllCatalogs(catalogController);
		confs = jobConfController.getAllJobConfs();

		jsonRoot = new AjaxResult();
		if ("createSubmit".equals(action)) {
			ajaxCreate();
		} else if ("editSubmit".equals(action)) {
			ajaxEditSubmit();
		}
		return "json";
	}

	@Override
	public String execute() throws Exception {
		defineTypes = ParameterDefineType.values();
		catalogs = Utils.getAllCatalogs(catalogController);
		confs = jobConfController.getAllJobConfs();

		if ("create".equals(action)) {
			return create();
		} else if ("createSubmit".equals(action)) {
			return createSubmit();
		} else if ("view".equals(action)) {
			return view();
		} else if ("edit".equals(action)) {
			return edit();
		} else if ("editSubmit".equals(action)) {
			return editSubmit();
		} else {
			message = "Unknown action: " + action;
			return SUCCESS;
		}
	}

	private String create() throws DaoException {
		if (identifier != null) {
			conf = jobConfController.getJobConf(identifier);
			if (conf == null) {
				message = "Job Configuration [" + identifier + "] not found.";
				return SUCCESS;
			} else {
				// 根据现有JobConf来设置新JobConf的初始值
				setByConf(conf);
			}
		} else {
			this.loopStep = 1;
			this.loopDependency = true;
		}
		return "create";
	}

	private void setByConf(JobConf conf) throws DaoException {
		this.catalog = conf.getCatalog();
		this.confName = conf.getName();
		this.confDesc = conf.getDescription();
		this.confType = conf.getType();
		this.maxRetry = conf.getMaxRetry();
		if (CmdJobConf.JOB_TYPE.equals(conf.getType())) {
			this.confContent = ((CmdJobConf) conf).getCmd();
			this.resource = conf.getResource();
		} else if (CompoundJobConf.JOB_TYPE.equals(conf.getType())) {
			List<JobDefine> list = ((CompoundJobConf) conf).getJobs();
			if (list != null && list.size() > 0) {
				this.subJob = new Identifier[list.size()];
				this.subJobDepend = new String[list.size() + 1];
				this.subJobCondition = new String[list.size() + 1];
				subJobDepend[0] = "";
				subJobCondition[0] = "";
				int index = 0;
				List<String> paraList = new ArrayList<String>();
				for (JobDefine jd : list) {
					subJob[index++] = jd.getIdentifier();
					Map<String, String> map = jd.getParameters();
					JobConf c = jobConfController.getJobConf(jd.getIdentifier());
					if (c.getParameterSize() > 0) {
						for (ParameterDefine pd : c.getParameters()) {
							String val = map != null ? map.get(pd.getName()) : null;
							paraList.add(val == null ? "" : val);
						}
					}
					Set<Integer> set = jd.getDependencies();
					subJobDepend[index] = set == null || set.isEmpty() ? "" : StringUtils.join(set, ',');
					subJobCondition[index] = jd.getCondition() == null ? "" : jd.getCondition();
				}
				this.subJobPara = paraList.toArray(new String[paraList.size()]);
			}
		} else if (LoopJobConf.JOB_TYPE.equals(conf.getType())) {
			this.loopVar = ((LoopJobConf) conf).getLoopVar();
			this.loopType = ((LoopJobConf) conf).getLoopType();
			this.loopFrom = ((LoopJobConf) conf).getLoopFrom();
			this.loopTo = ((LoopJobConf) conf).getLoopTo();
			this.loopStep = ((LoopJobConf) conf).getLoopStep();
			this.loopDependency = ((LoopJobConf) conf).isLoopDependency();
			JobDefine jd = ((LoopJobConf) conf).getSubJob();
			this.subJob = new Identifier[] { jd.getIdentifier() };
			this.subJobDepend = new String[] { "", "" };
			this.subJobCondition = new String[] { "", jd.getCondition() == null ? "" : jd.getCondition() };
			List<String> paraList = new ArrayList<String>();
			Map<String, String> map = jd.getParameters();
			JobConf c = jobConfController.getJobConf(jd.getIdentifier());
			if (c.getParameterSize() > 0) {
				for (ParameterDefine pd : c.getParameters()) {
					String val = map != null ? map.get(pd.getName()) : null;
					paraList.add(val == null ? "" : val);
				}
			}
			this.subJobPara = paraList.toArray(new String[paraList.size()]);
		}
		if (conf.getParameterSize() > 0) {
			int size = conf.getParameterSize();
			this.paraName = new String[size];
			this.paraType = new ParameterDefineType[size];
			this.paraValue = new String[size];
			int i = 0;
			for (ParameterDefine parameter : conf.getParameters()) {
				this.paraName[i] = parameter.getName();
				this.paraType[i] = parameter.getType();
				this.paraValue[i++] = parameter.getValue();
			}
		}
	}

	private void ajaxCreate() throws DaoException {
		if (StringUtils.isBlank(confType) || catalog == 0) {
			message = "请填写正确的数据。";
		} else if (StringUtils.isBlank(confName)) {
			message = "请填写Job名称。";
		} else {
			JobConf jobConf = createJobConf();
			if (jobConf != null) {
				jobConf.setName(confName);
				jobConf.setCatalog(catalog);
				jobConf.setDescription(confDesc);
				jobConf.setResource(resource);
				jobConf.setMaxRetry(maxRetry);
				jobConf.setOwner(user);
				if (setParameters(jobConf)) {
					try {
						identifier = jobConfController.addJobConf(jobConf);
						message = "Job Configuration [" + identifier.getStringIdentifier() + "] created.";
						operate(OperateType.conf_add, identifier);
						jsonRoot.ok(jobConf);
					} catch (DaoException e) {
						message = e.getLocalizedMessage();
					}
				}
			}
		}
		if (!jsonRoot.ok()) {
			jsonRoot.error(message);
		}
	}

	private String createSubmit() throws DaoException {
		if (StringUtils.isBlank(confType) || catalog == 0) {
			message = "请填写正确的数据。";
		} else if (StringUtils.isBlank(confName)) {
			message = "请填写Job名称。";
		} else {
			JobConf jobConf = createJobConf();
			if (jobConf != null) {
				jobConf.setName(confName);
				jobConf.setCatalog(catalog);
				jobConf.setDescription(confDesc);
				jobConf.setResource(resource);
				jobConf.setMaxRetry(maxRetry);
				jobConf.setOwner(user);
				if (setParameters(jobConf)) {
					try {
						identifier = jobConfController.addJobConf(jobConf);
						message = "Job Configuration [" + identifier.getStringIdentifier() + "] created.";
						operate(OperateType.conf_add, identifier);
						return "viewConf";
					} catch (DaoException e) {
						message = e.getLocalizedMessage();
					}
				}
			}
		}
		return "create";
	}

	private JobConf createJobConf() throws DaoException {
		if (CmdJobConf.JOB_TYPE.equals(confType)) {
			if (StringUtils.isBlank(confContent)) {
				message = "请填写命令行参数。";
				return null;
			}
			CmdJobConf conf = new CmdJobConf();
			conf.setCmd(confContent.trim());
			return conf;
		} else if (CompoundJobConf.JOB_TYPE.equals(confType)) {
			CompoundJobConf conf = new CompoundJobConf();
			return setSubJobs(conf) ? conf : null;
		} else if (LoopJobConf.JOB_TYPE.equals(confType)) {
			if (StringUtils.isBlank(loopVar)) {
				message = "请填写循环变量。";
				return null;
			} else if (StringUtils.isBlank(loopFrom)) {
				message = "请填写循环开始值。";
				return null;
			} else if (StringUtils.isBlank(loopTo)) {
				message = "请填写循环结束值。";
				return null;
			} else if (loopStep == 0) {
				message = "循环步长不能为0。";
				return null;
			}
			LoopJobConf conf = new LoopJobConf();
			conf.setLoopVar(loopVar.trim());
			conf.setLoopType(loopType);
			conf.setLoopFrom(loopFrom.trim());
			conf.setLoopTo(loopTo.trim());
			conf.setLoopStep(loopStep);
			conf.setLoopDependency(loopDependency);
			return setSubJobs(conf) ? conf : null;
		} else {
			message = "不支持的Job类型：" + confType;
			return null;
		}
	}

	private String view() throws DaoException, SchedulerException {
		conf = jobConfController.getJobConf(identifier);
		if (conf == null) {
			message = "Job Configuration [" + identifier + "] not found.";
			return SUCCESS;
		}

		operate(OperateType.conf_view, identifier);

		parentConfs = new ArrayList<JobConf>();
		for (JobConf c : jobConfController.getAllJobConfs()) {
			if (containJob(c, identifier)) {
				parentConfs.add(c);
			}
		}

		fireConfs = new ArrayList<JobConf>();
		for (JobDependency dependency : jobDependencyController.getAllJobDependencies()) {
			if (containJob(dependency, identifier)) {
				JobConf c = jobConfController.getJobConf(dependency.getJobConfIdentifier());
				if (c != null && !fireConfs.contains(c)) {
					fireConfs.add(c);
				}
			}
		}

		triggers = new ArrayList<Trigger>();
		for (TriggerKey key : scheduler.getTriggerKeys(GroupMatcher.triggerGroupEquals(conf.getIdentifier()
				.getStringIdentifier()))) {
			triggers.add(scheduler.getTrigger(key));
		}
		dependencies = jobDependencyController.getJobDependencies(identifier);

		jobs = jobController.getJobs(identifier);

		return "view-" + conf.getType();
	}

	private static boolean containJob(JobConf conf, Identifier identifier) {
		if (CompoundJobConf.JOB_TYPE.equals(conf.getType())) {
			for (JobDefine jd : ((CompoundJobConf) conf).getJobs()) {
				if (identifier.equals(jd.getIdentifier())) {
					return true;
				}
			}
		} else if (LoopJobConf.JOB_TYPE.equals(conf.getType())) {
			JobDefine jd = ((LoopJobConf) conf).getSubJob();
			return identifier.equals(jd.getIdentifier());
		}
		return false;
	}

	private static boolean containJob(JobDependency dep, Identifier identifier) {
		for (JobDependencyItem item : dep.getDependencies()) {
			if (identifier.equals(item.getIdentifier())) {
				return true;
			}
		}
		return false;
	}

	private String edit() throws DaoException, SchedulerException {
		conf = jobConfController.getJobConf(identifier);
		if (conf != null) {
			if (!conf.getOwner().equals(user) && !isSuperVisor()) {
				message = "Access Denied.";
				return view();
			}
			setByConf(conf);
		} else {
			message = "Job Configuration [" + identifier + "] not found.";
			return SUCCESS;
		}
		return "edit-" + conf.getType();
	}

	private void ajaxEditSubmit() throws DaoException, SchedulerException {
		conf = jobConfController.getJobConf(identifier);
		if (conf != null) {
			if (!conf.getOwner().equals(user) && !isSuperVisor()) {
				message = "Access Denied.";
			}
			if (StringUtils.isBlank(confName)) {
				message = "请填写Job名称。";
			} else if (editJobConf(conf)) {
				conf.setCatalog(catalog);
				conf.setName(confName);
				conf.setDescription(confDesc);
				conf.setResource(resource);
				conf.setMaxRetry(maxRetry);
				conf.setModifier(user);
				if (setParameters(conf)) {
					try {
						jobConfController.updateJobConf(conf);
						message = "Job Configuration [" + identifier.getStringIdentifier() + "] Saved.";
						operate(OperateType.conf_update, identifier);
						jsonRoot.ok(conf);
					} catch (DaoException e) {
						message = e.getLocalizedMessage();
					}
				}
			}
		} else {
			message = "Job Configuration [" + identifier + "] not found.";
		}
		if (!jsonRoot.ok()) {
			jsonRoot.error(message);
		}
	}

	private String editSubmit() throws DaoException, SchedulerException {
		conf = jobConfController.getJobConf(identifier);
		if (conf != null) {
			if (!conf.getOwner().equals(user) && !isSuperVisor()) {
				message = "Access Denied.";
				return view();
			}
			if (StringUtils.isBlank(confName)) {
				message = "请填写Job名称。";
			} else if (editJobConf(conf)) {
				conf.setCatalog(catalog);
				conf.setName(confName);
				conf.setDescription(confDesc);
				conf.setResource(resource);
				conf.setMaxRetry(maxRetry);
				conf.setModifier(user);
				if (setParameters(conf)) {
					try {
						jobConfController.updateJobConf(conf);
						message = "Job Configuration [" + identifier.getStringIdentifier() + "] Saved.";
						operate(OperateType.conf_update, identifier);
						return "viewConf";
					} catch (DaoException e) {
						message = e.getLocalizedMessage();
					}
				}
			}
		} else {
			message = "Job Configuration [" + identifier + "] not found.";
			return SUCCESS;
		}
		return "edit-" + conf.getType();
	}

	private boolean editJobConf(JobConf conf) throws DaoException {
		if (CmdJobConf.JOB_TYPE.equals(conf.getType())) {
			if (StringUtils.isBlank(confContent)) {
				return returnWithError("请填写命令行参数。");
			}
			((CmdJobConf) conf).setCmd(confContent.trim());
		} else if (CompoundJobConf.JOB_TYPE.equals(conf.getType())) {
			return setSubJobs((CompoundJobConf) conf);
		} else if (LoopJobConf.JOB_TYPE.equals(conf.getType())) {
			if (StringUtils.isBlank(loopVar)) {
				return returnWithError("请填写循环变量。");
			} else if (StringUtils.isBlank(loopFrom)) {
				return returnWithError("请填写循环开始值。");
			} else if (StringUtils.isBlank(loopTo)) {
				return returnWithError("请填写循环结束值。");
			} else if (loopStep == 0) {
				return returnWithError("循环步长不能为0。");
			}
			((LoopJobConf) conf).setLoopVar(loopVar.trim());
			((LoopJobConf) conf).setLoopType(loopType);
			((LoopJobConf) conf).setLoopFrom(loopFrom.trim());
			((LoopJobConf) conf).setLoopTo(loopTo.trim());
			((LoopJobConf) conf).setLoopStep(loopStep);
			((LoopJobConf) conf).setLoopDependency(loopDependency);
			return setSubJobs((LoopJobConf) conf);
		} else {
			return returnWithError("不支持的Job类型：" + conf.getType());
		}
		return true;
	}

	private boolean setParameters(JobConf conf) {
		if (paraName != null && paraName.length > 0) {
			List<ParameterDefine> params = new ArrayList<ParameterDefine>();
			for (int i = 0; i < paraName.length; i++) {
				try {
					if (!StringUtils.isBlank(paraName[i])) {
						params.add(new ParameterDefine(paraName[i].trim(), paraType[i], paraValue[i].trim()));
					}
				} catch (Throwable e) {
					return returnWithError("参数：" + paraName[i] + " 格式错误：" + e.getLocalizedMessage());
				}
			}
			conf.setParameters(params);
		} else {
			conf.setParameters(null);
		}
		return true;
	}

	private boolean setSubJobs(final CompoundJobConf conf) throws DaoException {
		if (subJob == null || subJob.length == 0) {
			return returnWithError("至少要有一个子Job");
		}
		conf.clearJobs();
		return setSubJobs(new SubJobSetter() {
			@Override
			public void addSubJob(Identifier jobIdentifier, Map<String, String> parameters, Set<Integer> dependencies,
					String condition) {
				conf.addJob(jobIdentifier, parameters, dependencies, condition);
			}
		});
	}

	private boolean setSubJobs(final LoopJobConf conf) throws DaoException {
		if (subJob == null || subJob.length != 1) {
			return returnWithError("有且只能有一个子Job");
		}
		return setSubJobs(new SubJobSetter() {
			@Override
			public void addSubJob(Identifier jobIdentifier, Map<String, String> parameters, Set<Integer> dependencies,
					String condition) {
				conf.setSubJob(jobIdentifier, parameters, condition);
			}
		});
	}

	private boolean setSubJobs(SubJobSetter setter) throws DaoException {
		int jobIndex = 0;
		int paraIndex = 0;
		for (Identifier id : subJob) {
			JobConf c = jobConfController.getJobConf(id);
			if (c == null) {
				return returnWithError("未知的JobConf：" + id.getStringIdentifier());
			}
			// 设置子Job参数
			Map<String, String> map = null;
			if (c.getParameterSize() > 0) {
				map = new HashMap<String, String>();
				for (ParameterDefine pd : c.getParameters()) {
					String val = subJobPara[paraIndex++];
					if (!StringUtils.isBlank(val)) {
						map.put(pd.getName(), val.trim());
					}
				}
				try {
					JobUtils.getJobParameters(c, map, false);
				} catch (IllegalArgumentException e) {
					return returnWithError("Job " + id.getStringIdentifier() + " 的" + e.getLocalizedMessage());
				}
			}

			// 设置子Job依赖
			Set<Integer> set = null;
			String depend = subJobDepend[++jobIndex];
			if (!StringUtils.isBlank(depend)) {
				set = new HashSet<Integer>();
				for (String s : StringUtils.split(depend.trim(), ',')) {
					try {
						int i = Integer.parseInt(s);
						if (i <= 0 || i > subJob.length) {
							return returnWithError("子Job " + jobIndex + " 依赖错误：依赖项必须在1-" + subJob.length + "之间");
						} else if (i == jobIndex) {
							return returnWithError("子Job " + jobIndex + " 依赖错误：不能依赖自己");
						} else {
							set.add(i);
						}
					} catch (Throwable e) {
						return returnWithError("子Job " + jobIndex + " 依赖错误：依赖项必须为数字：" + e.getLocalizedMessage());
					}
				}
			}

			// 设置条件
			String condition = subJobCondition[jobIndex];
			if (StringUtils.isBlank(condition)) {
				condition = null;
			} else {
				condition = condition.trim();
			}

			// 添加子Job信息
			setter.addSubJob(id, map, set, condition);
		}
		return true;
	}

	private boolean returnWithError(String message) {
		this.message = message;
		return false;
	}

	private static interface SubJobSetter {
		void addSubJob(Identifier jobIdentifier, Map<String, String> parameters, Set<Integer> dependencies,
				String condition);
	}

}
